package net.apexes.commons.lang;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @author <a href=mailto:hedyn@foxmail.com>HeDYn</a>
 */
public final class Collects {

    private Collects() {}

    /**
     * 将指定集合分折成多个大小不大于 limit 的小列表
     * @param srcs 需要拆分的容器
     * @param batchLimit 每个小列表中的最大元素数量
     * @return 返回拆分后的所有小列表
     */
    public static <T> List<List<T>> splitLimit(Collection<T> srcs, int batchLimit) {
        List<List<T>> resultList = new ArrayList<>();
        List<T> subList = new ArrayList<>();
        for (T src : srcs) {
            subList.add(src);
            if (subList.size() >= batchLimit) {
                resultList.add(subList);
                subList = new ArrayList<>();
            }
        }
        if (Checks.isNotEmpty(subList)) {
            resultList.add(subList);
        }
        return resultList;
    }

    /**
     * 按指定数量拆分小列表
     * @param srcs 需要拆分的容器
     * @param splitCount 小列表个数
     * @return 返回拆分后的所有小列表
     */
    public static <T> List<List<T>> splitCount(Collection<T> srcs, int splitCount) {
        List<List<T>> list = new ArrayList<>();
        int size = Math.min(srcs.size(), splitCount);
        for (int i = 0; i < size; i++) {
            list.add(new ArrayList<>());
        }
        int i = 0;
        for (T src : srcs) {
            if (i == size) {
                i = 0;
            }
            List<T> subList = list.get(i);
            subList.add(src);
            i++;
        }
        return list;
    }

    /**
     * 按指定数量拆分Map
     * @param map 需要拆分的Map
     * @param splitCount 拆分出的小Map的最大个数
     * @return 返回拆分后的所有小Map
     */
    public static <K, V> List<Map<K, V>> splitCount(Map<K, V> map, int splitCount) {
        List<Map<K, V>> list = new ArrayList<>();
        int size = Math.min(map.size(), splitCount);
        for (int i = 0; i < size; i++) {
            list.add(new LinkedHashMap<K, V>());
        }
        int i = 0;
        for (Map.Entry<K, V> entry : map.entrySet()) {
            if (i == size) {
                i = 0;
            }
            Map<K, V> subMap = list.get(i);
            subMap.put(entry.getKey(), entry.getValue());
            i++;
        }
        return list;
    }
}
